#include <54func.h>
//目标：实现两个买票窗口
typedef struct shareRes_s{
    int sticketNum;//票
    pthread_mutex_t mutex;//互斥锁
    pthread_cond_t cond;//条件变量
}shareRes_t;

void *sellWindow1(void *arg)
{
    shareRes_t *pshareRes = (shareRes_t *)arg;
    while(1)
    {
        //读共享资源时要加锁
        pthread_mutex_lock(&pshareRes->mutex);
        if(pshareRes->sticketNum <= 0)
        {
            pthread_mutex_unlock(&pshareRes->mutex);
            break;
        }
        printf("Before window1：ticketNum = %d\n",pshareRes->sticketNum);
        --pshareRes->sticketNum;
        if(pshareRes->sticketNum <= 10)
        {
            pthread_cond_signal(&pshareRes->cond);
        }
        printf("After window1：ticketNum = %d\n",pshareRes->sticketNum);
        pthread_mutex_unlock(&pshareRes->mutex);
        sleep(1);
    }
    pthread_exit(NULL);
}

void *sellWindow2(void *arg)
{
    shareRes_t *pshareRes = (shareRes_t *)arg;
    while(1)
    {
        pthread_mutex_lock(&pshareRes->mutex);
        if(pshareRes->sticketNum <= 0)
        {
            pthread_mutex_unlock(&pshareRes->mutex);
            break;
        }
        printf("Before window2：ticketNum = %d\n",pshareRes->sticketNum);
        --pshareRes->sticketNum;
        if(pshareRes->sticketNum <= 10)
        {
            pthread_cond_signal(&pshareRes->cond);
        }
        printf("After window2：ticketNum = %d\n",pshareRes->sticketNum);
        pthread_mutex_unlock(&pshareRes->mutex);
        sleep(1);
    }
    pthread_exit(NULL);
}

// 这个加票窗口线程只会执行一次，执行完加票便会退出
void *addWindow(void *arg)
{
    shareRes_t * pshareRes = (shareRes_t *)arg;
    
    pthread_mutex_lock(&pshareRes->mutex);
    if(pshareRes->sticketNum > 10)
    {
        printf("stick is enouhg now!\n");
        //如果票超过 10 张，不需要加票，等待即可，当等待的找执行后，会带锁返回，此时在加票，因此wait操作在你要实施操作之前
        pthread_cond_wait(&pshareRes->cond,&pshareRes->mutex);//等待

    }
    
    //当上述条件执行结束后，说明票数已经不够用了这里其实要解锁，但是下面操作也是共享资源，因此可以让临界区大一些
    pshareRes->sticketNum += 10;
    pthread_mutex_unlock(&pshareRes->mutex);
    pthread_exit(NULL);
}
int main()
{
    shareRes_t shareRes;
    shareRes.sticketNum = 20;
    pthread_mutex_init(&shareRes.mutex,NULL);//初始化锁
    pthread_cond_init(&shareRes.cond,NULL);  //初始化条件变量

    pthread_t tid1,tid2,tid3;
    pthread_create(&tid1,NULL,sellWindow1,&shareRes);
    pthread_create(&tid2,NULL,sellWindow2,&shareRes);
    pthread_create(&tid3,NULL,addWindow,&shareRes);

    pthread_join(tid1,NULL);
    pthread_join(tid2,NULL);
    pthread_join(tid3,NULL);

    return 0;
}
